import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import json
import os
from datetime import datetime, timedelta

class Card:
    def __init__(self, title, answer, tag):
        self.title = title
        self.answer = answer
        self.tag = tag
        self.proficiency = 50  # 初始熟练度
        self.last_practiced = datetime.now().isoformat()

    def to_dict(self):
        return {
            "title": self.title,
            "answer": self.answer,
            "tag": self.tag,
            "proficiency": self.proficiency,
            "last_practiced": self.last_practiced
        }

class CardManager:
    def __init__(self):
        self.cards = []
        self.load_data()

    def load_data(self):
        if os.path.exists("cards.json"):
            with open("cards.json", "r") as f:
                data = json.load(f)
                self.cards = [self.dict_to_card(d) for d in data]

    def save_data(self):
        with open("cards.json", "w") as f:
            data = [card.to_dict() for card in self.cards]
            json.dump(data, f, indent=2)

    def dict_to_card(self, data):
        card = Card(data["title"], data["answer"], data["tag"])
        card.proficiency = data["proficiency"]
        card.last_practiced = data["last_practiced"]
        return card

    def add_card(self, card):
        self.cards.append(card)
        self.save_data()

    def get_tags(self):
        return list(set(card.tag for card in self.cards))

class MainApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Card Memory System")
        self.geometry("800x600")
        self.card_manager = CardManager()
        
        self.setup_ui()
        self.setup_menu()
        self.bind_shortcuts()

    def setup_ui(self):
        main_frame = ttk.Frame(self)
        main_frame.pack(fill=tk.BOTH, expand=True)

        self.tree = ttk.Treeview(main_frame, columns=("proficiency",), selectmode="browse")
        self.tree.heading("#0", text="Cards")
        self.tree.heading("proficiency", text="Proficiency")
        self.tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.refresh_treeview()
        self.tree.bind("<Button-3>", self.show_card_info)

    def setup_menu(self):
        menu_bar = tk.Menu(self)
        
        # File menu
        file_menu = tk.Menu(menu_bar, tearoff=0)
        file_menu.add_command(label="New Folder (N)", command=self.create_folder)
        file_menu.add_command(label="New Card (A)", command=self.create_card)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self.quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

        # View menu
        view_menu = tk.Menu(menu_bar, tearoff=0)
        view_menu.add_command(label="List Tags (T)", command=self.list_tags)
        menu_bar.add_cascade(label="View", menu=view_menu)

        # Study menu
        study_menu = tk.Menu(menu_bar, tearoff=0)
        study_menu.add_command(label="Start Study (S)", command=self.start_study)
        menu_bar.add_cascade(label="Study", menu=study_menu)

        # Help menu
        help_menu = tk.Menu(menu_bar, tearoff=0)
        help_menu.add_command(label="Help (H)", command=self.show_help)
        menu_bar.add_cascade(label="Help", menu=help_menu)

        self.config(menu=menu_bar)

    def bind_shortcuts(self):
        self.bind("n", lambda e: self.create_folder())
        self.bind("a", lambda e: self.create_card())
        self.bind("t", lambda e: self.list_tags())
        self.bind("s", lambda e: self.start_study())
        self.bind("h", lambda e: self.show_help())

    def refresh_treeview(self):
        self.tree.delete(*self.tree.get_children())
        tags = self.card_manager.get_tags()
        for tag in tags:
            parent = self.tree.insert("", "end", text=tag, values=(""))
            for card in [c for c in self.card_manager.cards if c.tag == tag]:
                self.tree.insert(parent, "end", text=card.title, values=(card.proficiency))

    def create_folder(self):
        tag = simpledialog.askstring("New Folder", "Enter tag name:")
        if tag:
            self.refresh_treeview()

    def create_card(self):
        dialog = CardDialog(self)
        self.wait_window(dialog)
        if dialog.card_data:
            new_card = Card(**dialog.card_data)
            self.card_manager.add_card(new_card)
            self.refresh_treeview()

    def list_tags(self):
        tags = self.card_manager.get_tags()
        messagebox.showinfo("Tags", "\n".join(tags) if tags else "No tags found")

    def start_study(self):
        StudyWindow(self, self.card_manager)

    def show_card_info(self, event):
        item = self.tree.identify_row(event.y)
        if item:
            card_title = self.tree.item(item, "text")
            card = next(c for c in self.card_manager.cards if c.title == card_title)
            info = f"Title: {card.title}\nTag: {card.tag}\nProficiency: {card.proficiency}\nLast Practiced: {card.last_practiced}"
            messagebox.showinfo("Card Info", info)

    def show_help(self):
        help_text = """Shortcuts:
N - Create new folder
A - Create new card
T - List tags
S - Start study
H - Show help"""
        messagebox.showinfo("Help", help_text)

class CardDialog(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)
        self.title("New Card")
        self.card_data = None
        
        ttk.Label(self, text="Title:").grid(row=0, column=0, padx=5, pady=5)
        self.title_entry = ttk.Entry(self)
        self.title_entry.grid(row=0, column=1, padx=5, pady=5)
        
        ttk.Label(self, text="Answer:").grid(row=1, column=0, padx=5, pady=5)
        self.answer_entry = ttk.Entry(self)
        self.answer_entry.grid(row=1, column=1, padx=5, pady=5)
        
        ttk.Label(self, text="Tag:").grid(row=2, column=0, padx=5, pady=5)
        self.tag_entry = ttk.Entry(self)
        self.tag_entry.grid(row=2, column=1, padx=5, pady=5)
        
        btn_frame = ttk.Frame(self)
        btn_frame.grid(row=3, column=0, columnspan=2, pady=10)
        ttk.Button(btn_frame, text="Create", command=self.on_create).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="Cancel", command=self.destroy).pack(side=tk.RIGHT, padx=5)

    def on_create(self):
        self.card_data = {
            "title": self.title_entry.get(),
            "answer": self.answer_entry.get(),
            "tag": self.tag_entry.get()
        }
        self.destroy()

class StudyWindow(tk.Toplevel):
    def __init__(self, parent, card_manager):
        super().__init__(parent)
        self.title("Study Mode")
        self.geometry("600x400")
        self.card_manager = card_manager
        self.current_card = 0
        
        self.cards = self.filter_cards()
        if not self.cards:
            messagebox.showinfo("Info", "No cards to study!")
            self.destroy()
            return
        
        self.setup_ui()
        self.show_card()
        self.bind_keys()

        self.focus_set()
        self.grab_set()

    def filter_cards(self):
        now = datetime.now()
        valid_cards = []
        for card in self.card_manager.cards:
            last_practiced = datetime.fromisoformat(card.last_practiced)
            delta = now - last_practiced
            if delta > timedelta(hours=6) and card.proficiency < 100:
                card.proficiency = max(0, card.proficiency - 20)
                card.last_practiced = now.isoformat()
            if card.proficiency < 100 or (now - last_practiced) < timedelta(days=3):
                valid_cards.append(card)
        return sorted(valid_cards, key=lambda c: c.proficiency)

    def setup_ui(self):
        self.top_frame = ttk.Frame(self)
        self.top_frame.pack(pady=20)
        
        self.title_label = ttk.Label(self.top_frame, text="", font=("Arial", 16))
        self.title_label.pack()
        
        self.answer_label = ttk.Label(self.top_frame, text="", font=("Arial", 12))
        
        btn_frame = ttk.Frame(self)
        btn_frame.pack(side=tk.BOTTOM, pady=10)
        ttk.Button(btn_frame, text="Unfamiliar (1)", command=lambda: self.rate_card(1)).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="OK (2)", command=lambda: self.rate_card(2)).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="Mastered (3)", command=lambda: self.rate_card(3)).pack(side=tk.LEFT, padx=5)

    def bind_keys(self):
        # 修改为更可靠的事件绑定方式
        self.bind("<Key-space>", lambda e: self.toggle_answer())
        self.bind("<Key-q>", lambda e: self.prev_card())
        self.bind("<Key-e>", lambda e: self.next_card())
        self.bind("<Key-1>", lambda e: self.rate_card(1))
        self.bind("<Key-2>", lambda e: self.rate_card(2))
        self.bind("<Key-3>", lambda e: self.rate_card(3))
        
        # 兼容小键盘数字键
        self.bind("<Key-KP_1>", lambda e: self.rate_card(1))
        self.bind("<Key-KP_2>", lambda e: self.rate_card(2))
        self.bind("<Key-KP_3>", lambda e: self.rate_card(3))

    def show_card(self):
        card = self.cards[self.current_card]
        self.title_label.config(text=card.title)
        self.answer_label.config(text="")
        self.answer_label.pack_forget()

    def toggle_answer(self):
        if self.answer_label.winfo_ismapped():
            self.answer_label.pack_forget()
        else:
            card = self.cards[self.current_card]
            self.answer_label.config(text=card.answer)
            self.answer_label.pack()

    def prev_card(self):
        self.current_card = (self.current_card - 1) % len(self.cards)
        self.show_card()

    def next_card(self):
        self.current_card = (self.current_card + 1) % len(self.cards)
        self.show_card()

    def rate_card(self, rating):
        card = self.cards[self.current_card]
        if rating == 1:
            card.proficiency = max(0, card.proficiency - 20)
        elif rating == 3:
            card.proficiency = min(100, card.proficiency + 20)
        card.last_practiced = datetime.now().isoformat()
        self.card_manager.save_data()
        self.next_card()

if __name__ == "__main__":
    app = MainApp()
    app.mainloop()